package com.beyond.common.provider

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.datastore.preferences.core.Preferences
import com.beyond.common.dp.theme.CustomPrimaryColorPreference
import com.beyond.common.dp.theme.DarkModePreference
import com.beyond.common.dp.theme.SystemPrimaryColorPreference
import com.beyond.common.dp.theme.ThemeNamePreference
import com.beyond.common.ext.dataStore
import com.beyond.common.local.LocalCustomPrimaryColor
import com.beyond.common.local.LocalDarkMode
import com.beyond.common.local.LocalSystemPrimaryModel
import com.beyond.common.local.LocalThemeName
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map

fun Preferences.toThemeSettings(): ThemeSettings {
    return ThemeSettings(
        // Theme
        themeName = ThemeNamePreference.fromPreferences(this),
        customPrimaryColor = CustomPrimaryColorPreference.fromPreferences(this),
        systemPrimaryColor = SystemPrimaryColorPreference.fromPreferences(this),
        darkMode = DarkModePreference.fromPreferences(this),
    )
}

data class ThemeSettings(
    // Theme
    val themeName: String = ThemeNamePreference.default,
    val customPrimaryColor: String = CustomPrimaryColorPreference.default,
    val systemPrimaryColor: Boolean = SystemPrimaryColorPreference.default,
    val darkMode: Int = DarkModePreference.default,
)

@Composable
fun ThemeSettingsProvider(
    content: @Composable () -> Unit,
) {
    val context = LocalContext.current
    val settings = remember {
        context.dataStore.data.map { it.toThemeSettings() }
    }.collectAsState(initial = ThemeSettings(), context = Dispatchers.Default).value

    CompositionLocalProvider(
        // Theme
        LocalThemeName provides settings.themeName,
        LocalCustomPrimaryColor provides settings.customPrimaryColor,
        LocalSystemPrimaryModel provides settings.systemPrimaryColor,
        LocalDarkMode provides settings.darkMode,
    ) {
        content()
    }
}